From 1acc843a3ed324628c8935d806b69ce93062f27f Mon Sep 17 00:00:00 2001 From: tsteven4 <13596209+tsteven4@users.noreply.github.com> Date: Tue, 14 May 2019 08:06:59 -0600 Subject: [PATCH] Fix gbfputcstr when using non UTF-8 encoding. (#348) MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit * Fix gbfputcstr when using non UTF-8 encoding. This restores gbfputcstr from 75d8ec00f^. That change could result in implicit conversion of char* data that was specifically encoded as required for a format to UTF-16, and then explicitly converted from UTF-16 to UTF-8. While this was inefficient it could also result in corruption when the data to be written was encoded in something other than UTF-8. For example, the Latin1 encoded 'ö' is '\xf6' will be converted to the UTF-16 replacement character, and that will be converter to the UTF-8 replacement character, not the original character. This resolves a mystery that was noted in the gdb test where some strings where corrupted when writing gdb versions 1 and 2. Instead of using function overloading I deleted the version of gbfputcstr that accepted a QString to write, forcing the user to specifically convert the data as appropriate. * increase accuracy of GPS_Math_Deg_To_Semi. Use rounding of the calculated floating point value before conversion to an integer to improve accuracy. This minimizes abs(GPS_Math_Semi_to_Deg(GPS_Math_Deg_To_Semi(fpvalue)) - fpvalue). This allows us do some round trip testing from formats that use a textual representations of degrees, e.g. gpx, to a binary format that stores integer represetations of angles in semicircle units, and back. It is still possible for round trip differences to occur, but in all our test cases this hasn't been observed. The value, the number of decimal places printed for the textual representation, and the size of floating point variables can all influence this. Two GPSBabel generated binary reference files are updated. All changes in these files are 1 bit changes in latitude or longitude values as can be expected from the difference between truncation and rounding. Two GPSBabel generated gpx reference files are deleted as the source of the round trip test can be compared to the output now. A gdb test comparison is now enabled as the round trip results now match. * enhance gdb test. adding a roundtrip test with gdb version 3. --- easygps.cc | 2 +- gbfile.cc | 15 +- gbfile.h | 2 +- jeeps/gpsmath.cc | 2 +- lmx.cc | 21 +- reference/garmin_gpi2.gpx | 521 ------------------------- reference/garmin_gpi_category~gpx.gpi | Bin 5272 -> 5272 bytes reference/garmin_gpi_encoding2.gpi.gpx | 13 - reference/netstumbler.mps | Bin 4838 -> 4838 bytes testo.d/garmin_gpi.test | 4 +- testo.d/gdb.test | 24 +- 11 files changed, 38 insertions(+), 566 deletions(-) delete mode 100644 reference/garmin_gpi2.gpx delete mode 100644 reference/garmin_gpi_encoding2.gpi.gpx diff --git a/easygps.cc b/easygps.cc index 8f8ef7794..a9ba3224f 100644 --- a/easygps.cc +++ b/easygps.cc @@ -181,7 +181,7 @@ ez_disp(const Waypoint* wpt) } if (!link.url_.isEmpty()) { gbfputc(9, file_out); - gbfputcstr(link.url_, file_out); + gbfputcstr(CSTRc(link.url_), file_out); } } gbfputc(0xff, file_out); diff --git a/gbfile.cc b/gbfile.cc index 10a705216..85633208b 100644 --- a/gbfile.cc +++ b/gbfile.cc @@ -1211,16 +1211,19 @@ gbfputflt(const float f, gbfile* file) * return the number of written characters */ int -gbfputcstr(const QString& s, gbfile* file) +gbfputcstr(const char* s, gbfile* file) { - QByteArray qs = s.toUtf8(); - int rv = gbfwrite(qs.constData(), 1, qs.size(), file); - gbfputc(0, file); - return rv; + int len = (s == nullptr) ? 0 : strlen(s); + if (len > 0) { + return gbfwrite(s, 1, len + 1, file); + } else { + gbfputc(0, file); + return 1; + } } /* - * gbfputcstr: write a pascal string into a stream + * gbfputpstr: write a pascal string into a stream * return the number of written characters */ diff --git a/gbfile.h b/gbfile.h index 3a1b87bbc..1c4cf89d7 100644 --- a/gbfile.h +++ b/gbfile.h @@ -127,7 +127,7 @@ int gbfputint32(int32_t i, gbfile* file); int gbfputdbl(double d, gbfile* file); // write a double value int gbfputflt(float f, gbfile* file); // write a float value -int gbfputcstr(const QString& s, gbfile* file); // write string including '\0' +int gbfputcstr(const char* s, gbfile* file); // write string including '\0' int gbfputpstr(const QString& s, gbfile* file); // write as pascal string diff --git a/jeeps/gpsmath.cc b/jeeps/gpsmath.cc index b71654ae5..1bb3e5ab3 100644 --- a/jeeps/gpsmath.cc +++ b/jeeps/gpsmath.cc @@ -249,7 +249,7 @@ double GPS_Math_Feet_To_Metres(double v) int32 GPS_Math_Deg_To_Semi(double v) { - return ((double)(1U<<31) / 180.0) * v; + return round(((double)(1U<<31) / 180.0) * v); } diff --git a/lmx.cc b/lmx.cc index 8dd57a5ac..a05bc93fa 100644 --- a/lmx.cc +++ b/lmx.cc @@ -26,10 +26,13 @@ * we don't implement that at this time in GPSBabel. */ +#include // for QString +#include // for QXmlStreamAttributes + #include "defs.h" -#include "xmlgeneric.h" -#include -#include +#include "gbfile.h" // for gbfputc, gbfprintf, gbfclose, gbfopen, gbfputcstr, gbfputs, gbfile, gbfputuint16 +#include "xmlgeneric.h" // for cb_cdata, xg_callback, xg_string, cb_end, cb_start, xg_cb_type, xml_deinit, xml_init, xml_read, xg_tag_mapping + static gbfile* ofd; static Waypoint* wpt_tmp; @@ -182,7 +185,7 @@ lmx_write_xml(int tag, const QString& data, int indent) if (binary) { gbfputc(0x03, ofd); // inline string follows - gbfputcstr(data, ofd); + gbfputcstr(CSTR(data), ofd); } else { char* tmp_ent = xml_entitize(CSTR(data)); gbfputs(tmp_ent, ofd); @@ -223,16 +226,12 @@ lmx_print(const Waypoint* wpt) gbfputc('\n', ofd); } - char tbuf[100]; - sprintf(tbuf, "%f", wpt->latitude); - lmx_write_xml(0x4B, tbuf, 4); // latitude + lmx_write_xml(0x4B, QString::number(wpt->latitude, 'f'), 4); // latitude - sprintf(tbuf, "%f", wpt->longitude); - lmx_write_xml(0x4C, tbuf, 4); // longitude + lmx_write_xml(0x4C, QString::number(wpt->longitude, 'f'), 4); // longitude if (wpt->altitude && (wpt->altitude != unknown_alt)) { - sprintf(tbuf, "%f", wpt->altitude); - lmx_write_xml(0x4D, tbuf, 4); // altitude + lmx_write_xml(0x4D, QString::number(wpt->altitude, 'f'), 4); // altitude } lmx_end_tag(0x4A, 3); // coordinates diff --git a/reference/garmin_gpi2.gpx b/reference/garmin_gpi2.gpx deleted file mode 100644 index 331b1057f..000000000 --- a/reference/garmin_gpi2.gpx +++ /dev/null @@ -1,521 +0,0 @@ - - - - - - 5058ROAD - ROAD CROSSING - ROAD CROSSING - Waypoint - - - 5066 - 5066 - 5066 - Waypoint - - - 5067 - 5067 - 5067 - Waypoint - - - 5096 - 5096 - 5096 - Waypoint - - - 5142 - 5142 - 5142 - Waypoint - - - 5144SUMMIT - Summit - Summit - Waypoint - - - 5148NANEPA - Nanepashemet Road Crossing - Nanepashemet Road Crossing - Waypoint - - - 5150TANK - WATER TANK - WATER TANK - Waypoint - - - 5156 - 5156 - 5156 - Waypoint - - - 5179DEAD - Dead End - Dead End - Waypoint - - - 5224 - 5224 - 5224 - Waypoint - - - 5229 - 5229 - 5229 - Waypoint - - - 5236BRIDGE - Bridge - Bridge - Waypoint - - - 5237 - 5237 - 5237 - Waypoint - - - 5239ROAD - Road - Road - Waypoint - - - 5252PURPLE - Purple Rock Hill - Purple Rock Hill - Waypoint - - - 5254 - 5254 - 5254 - Waypoint - - - 5258 - 5258 - 5258 - Waypoint - - - 5264 - 5264 - 5264 - Waypoint - - - 526708 - 526708 - 526708 - Waypoint - - - 526750 - 526750 - 526750 - Waypoint - - - 5267OBSTAC - Obstacle - Obstacle - Waypoint - - - 527614 - 527614 - 527614 - Waypoint - - - 527631 - 527631 - 527631 - Waypoint - - - 5278 - 5278 - 5278 - Waypoint - - - 5278ROAD - Road - Road - Waypoint - - - 5287WATER - Reservoir - Reservoir - Waypoint - - - 5289 - 5289 - 5289 - Waypoint - - - 5299DEAD - Dead End - Dead End - Waypoint - - - 5374FIRE - 5374FIRE - 5374FIRE - Waypoint - - - 5376 - 5376 - 5376 - Waypoint - - - 5376BRIDGE - Bridge - Bridge - Waypoint - - - 5376DEAD - Dead End - Dead End - Waypoint - - - 5376STREAM - Stream Crossing - Stream Crossing - Waypoint - - - 6006 - 600698 - 600698 - Waypoint - - - 6006BLUE - 6006BLUE - 6006BLUE - Waypoint - - - 6014MEADOW - 6014MEADOW - 6014MEADOW - Waypoint - - - 6016 - Bike Loop Connector - Bike Loop Connector - Waypoint - - - 6029 - 6029 - 6029 - Waypoint - - - 6042CROSS - Crossing - Crossing - Waypoint - - - 6053 - 6053 - 6053 - Waypoint - - - 6066 - 6066 - 6066 - Waypoint - - - 6067 - 6067 - 6067 - Waypoint - - - 6071 - 6071 - 6071 - Waypoint - - - 6073 - 6073 - 6073 - Waypoint - - - 6077LOGS - Log Crossing - Log Crossing - Waypoint - - - 6084 - 6084 - 6084 - Waypoint - - - 6121DEAD - Dead End - Dead End - Waypoint - - - 6130 - 6130 - 6130 - Waypoint - - - 6131 - 6131 - 6131 - Waypoint - - - 6153 - 6153 - 6153 - Waypoint - - - 6155DEAD - Dead End - Dead End - Waypoint - - - 6171 - 6171 - 6171 - Waypoint - - - 6176 - 6176 - 6176 - Waypoint - - - 6177 - 6177 - 6177 - Waypoint - - - 6181CROSS - Crossing - Crossing - Waypoint - - - 6272 - 6272 - 6272 - Waypoint - - - 6272.1 - 6272 - 6272 - Waypoint - - - 6278 - 6278 - 6278 - Waypoint - - - 6280 - 6280 - 6280 - Waypoint - - - 6283 - 6283 - 6283 - Waypoint - - - 6289 - 6289 - 6289 - Waypoint - - - 6297 - 6297 - 6297 - Waypoint - - - 6328 - 6328 - 6328 - Waypoint - - - 6353DEAD - Dead End - Dead End - Waypoint - - - 6354 - 6354 - 6354 - Waypoint - - - 635722 - 635722 - 635722 - Waypoint - - - 635783 - 635783 - 635783 - Waypoint - - - 6373 - 6373 - 6373 - Waypoint - - - 6634 - 6634 - 6634 - Waypoint - - - 6979 - 6979 - 6979 - Waypoint - - - 6997 - 6997 - 6997 - Waypoint - - - BEAR HILL - BEAR HILL TOWER - BEAR HILL TOWER - Waypoint - - - BELLEVUE - BELLEVUE - BELLEVUE - Waypoint - - - DARKHOLLPO - Dark Hollow Pond - Dark Hollow Pond - Waypoint - - - GATE14 - Gate 14 - Gate 14 - Waypoint - - - GATE16 - Gate 16 - Gate 16 - Waypoint - - - GATE17 - Gate 17 - Gate 17 - Waypoint - - - GATE19 - Gate 19 - Gate 19 - Waypoint - - - GATE21 - Gate 21 - Gate 21 - Waypoint - - - GATE24 - Gate 24 - Gate 24 - Waypoint - - - GATE5 - Gate 5 - Gate 5 - Waypoint - - - GATE6 - Gate 6 - Gate 6 - Waypoint - - - PANTHRCAVE - Panther Cave - Panther Cave - Waypoint - - - SHEEPFOLD - Sheepfold Parking Lot - Sheepfold Parking Lot - Waypoint - - - SOAPBOX - Soap Box Derby Track - Soap Box Derby Track - Waypoint - - diff --git a/reference/garmin_gpi_category~gpx.gpi b/reference/garmin_gpi_category~gpx.gpi index dcfda1bd8cc339fe6fa8def8732213adbf92bb81..d72f6bda6df28cc95d639249d81516c753bf073a 100644 GIT binary patch delta 150 zcmV;H0BQf2DVQm+SpxwGlUf6?0a%j@1b+c)vx@{@0RhXC>jminV3XAbc>&CmPX~1Y zXOqPT`T^3DzzE9$!IO*$asffJ{|Sr%0X&n83qk>5v(F1n0Raq?9SwE?hm({IHUVmr z%MIND!jq{EZ2`lR7Z2wF{geL>Isr~( EMeP$civR!s delta 150 zcmV;H0BQf2DVQm+SpxwHlUf6?0a=p^1b+c*vx@{@0RhaD>jminUz61ac>&FnPX~1Y zXp_YU`T^0CzzE9$!jp^%asfcI{|Sr%0Xvh73qk>6v(F1n0Ran>9SwE?hLe;HHUVjq z%MIND!IP;DZ2`iQ7Z2wF{FDC=Isr+OIuLCEbhD@sv;hHBvt1IX0Re`S1{6#I@sm>& EMeUR|ga7~l diff --git a/reference/garmin_gpi_encoding2.gpi.gpx b/reference/garmin_gpi_encoding2.gpi.gpx deleted file mode 100644 index f2b158400..000000000 --- a/reference/garmin_gpi_encoding2.gpi.gpx +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - € - ™ - ™ - Waypoint - - diff --git a/reference/netstumbler.mps b/reference/netstumbler.mps index c313182348d1eae58d4d4ff2e7046dd3296e030e..1862bedc55577763f416c172fd16064477a3fffc 100644 GIT binary patch delta 390 zcmaE+`b>4gHO91w*BjYZyS!CA6EQh~NqTZG7yIM}#&9-6<+q9)oG9W~K}ckiaCCIL4^S@ho+0F1z0-N>_qS`NtB+s(Ijz;;hMu zthH)4VR%O*c!Yhst?exvxT$YXK=r|jeo z_Gq>>Yu+m6`~)ld&;EkR=L=A~;$$w)WX5@u^Eg|XUOWbyw?L3}vH({i6W6WD&)F0v zPv(kdyfgVdR}W8{5g^gY4t)f9A%o*B3@k|$A!5zL_$Q}SE!j5DB delta 390 zcmaE+`b>4gHOAD5*BjYZxx7_86EQh~NqTZG7yIM}#&9+R<+q9)o)4VROD8{KYhst;exvxj$YXK=r|jeo z_Gq@%Yu+m6{sb%f&;EkR_X|+F;$$w)WXAcE^Eg|XUOon!w?L3}vH({i6Zfsj&)F0v zPv(kdygm6nR})1QR2WpcWdBrBn^JlO(pMIwptpSn##mX~zJ%1#!k_L7*U{J75))xq4Y?<69 q&;%qo1*_RwzPwee>W8{5g^f+